package com.bizdk.generator.controller.gen;

import com.bizdk.generator.common.page.PageResult;
import com.bizdk.generator.common.query.Query;
import com.bizdk.generator.common.utils.R;
import com.bizdk.generator.core.GenUtils;
import com.bizdk.generator.core.GenDataSrc;
import com.bizdk.generator.controller.SimpleController;
import com.bizdk.generator.entity.gen.Datasrc;
import com.bizdk.generator.entity.gen.Project;
import com.bizdk.generator.entity.gen.Table;
import com.bizdk.generator.entity.gen.TableColumn;
import com.bizdk.generator.service.DatasrcService;
import com.bizdk.generator.service.ProjectService;
import com.bizdk.generator.service.TableColumnService;
import com.bizdk.generator.service.TableService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据表管理
 */
@Slf4j
@AllArgsConstructor
@Controller
@RequestMapping("/gen/table")
public class TableController extends SimpleController<TableService, Table> {
    
    private final TableColumnService tableColumnService;
    
    private final ProjectService projectService;
    
    private final DatasrcService datasrcService;
    
    @Override
    protected String getPrefix() {
        return "gen/table";
    }
    
    @Override
    public ModelAndView list(Query query) {
        List<Datasrc> list = datasrcService.list();
        List<Project> projects = projectService.list();
        ModelAndView modelAndView = super.list(query);
        modelAndView.addObject("datasrcList", list);
        modelAndView.addObject("projects", projects);
        return modelAndView;
    }
    
    /**
     * 分页
     *
     * @param query 查询参数
     */
    @ResponseBody
    @RequestMapping("/page")
    public R<PageResult<Table>> page(Query query) {
        PageResult<Table> page = service.page(query);
        return R.ok(page);
    }
    
    @Override
    @GetMapping("/edit/{id}")
    public ModelAndView edit(@PathVariable("id") Long id) {
        Table data = service.getById(id);
        // 获取表的字段
        List<TableColumn> columnEntityList = tableColumnService.getByTableId(data.getId());
        data.setColumns(columnEntityList);
        
        ModelAndView modelAndView = super.edit(id);
        modelAndView.addObject("data", data);
        modelAndView.addObject("tableId", id);
        return modelAndView;
    }
    
    /**
     * 修改
     *
     * @param table 表信息
     */
    @ResponseBody
    @PutMapping("/update")
    public R<String> update(Table table) {
        service.updateById(table);
        return R.ok();
    }
    
    /**
     * 删除
     *
     * @param ids 表id数组
     */
    @ResponseBody
    @PostMapping("/delete")
    public R<String> delete(Long[] ids) {
        service.deleteBatchIds(ids);
        return R.ok();
    }
    
    
    @GetMapping("/createTable")
    public Object createTable(Query query) {
        return getPrefix() + "/createTable";
    }
    
    @GetMapping("/importTable")
    public Object importTable(Query query) {
        List<Datasrc> list = datasrcService.list();
        ModelAndView modelAndView = new ModelAndView(getPrefix() + "/importTable");
        modelAndView.addObject("datasrcList", list);
        return modelAndView;
    }
    
    /**
     * 根据数据源ID，获取全部数据表
     *
     * @param datasrcId 数据源ID
     */
    @ResponseBody
    @PostMapping("/table/list/{datasrcId}")
    public R<List<Table>> tableList(@PathVariable("datasrcId") Long datasrcId) {
        if (datasrcId < 1) {
            return R.ok(new ArrayList<>());
        }
        try {
            // 获取数据源
            GenDataSrc genDataSrc = datasrcService.get(datasrcId);
            // 根据数据源，获取全部数据表
            List<Table> tableList = GenUtils.getTableList(genDataSrc);
            
            return R.ok(tableList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return R.error("数据源配置错误，请检查数据源配置！");
        }
    }
    
    @ResponseBody
    @GetMapping("/list/{datasrcId}")
    public R<List<Table>> list(@PathVariable("datasrcId") Long datasrcId) {
        List<Table> tableEntities = service.tableList(datasrcId);
        return R.ok(tableEntities);
    }
    
    /**
     * 导入数据源中的表
     *
     * @param datasrcId     数据源ID
     * @param tableNameList 表名列表
     */
    @ResponseBody
    @PostMapping("/import/{datasrcId}")
    public R<String> tableImport(@PathVariable("datasrcId") Long datasrcId, @RequestParam List<String> tableNameList) {
        for (String tableName : tableNameList) {
            service.tableImport(datasrcId, tableName);
        }
        return R.ok();
    }
    
    /**
     * 修改表字段数据
     *
     * @param tableId 表ID
     * @param table   字段列表
     */
    @ResponseBody
    @PutMapping("/column/{tableId}")
    public R<String> updateTableColumn(@PathVariable("tableId") Long tableId, @RequestBody Table table) {
        service.updateById(table);
        tableColumnService.updateTableColumn(tableId, table.getColumns());
        return R.ok();
    }
    
    /**
     * 同步表结构
     *
     * @param tableId 表ID
     */
    @ResponseBody
    @GetMapping("/sync/{tableId}")
    public R<String> sync(@PathVariable("tableId") Long tableId) {
        service.sync(tableId);
        return R.ok();
    }
    
    @GetMapping("/gen")
    public Object gen(@RequestParam("tableIds") List<Long> tableIds,
            @RequestParam("tableNames") List<String> tableNames) {
        List<Project> projects = projectService.list();
        ModelAndView modelAndView = new ModelAndView(getPrefix() + "/gen");
        modelAndView.addObject("tableIds", tableIds);
        modelAndView.addObject("tableNames", tableNames);
        modelAndView.addObject("projects", projects);
        return modelAndView;
    }
}
